import {Config, Field} from 'alinea'
import {LocalDB} from 'alinea/core/db/LocalDB'
import {createMediaRoot} from 'alinea/core/media/MediaRoot'
import {MediaFile, MediaLibrary} from 'alinea/core/media/MediaTypes'

const Page = Config.document('Type', {
  contains: ['Page'],
  fields: {
    title: Field.text('Title'),
    path: Field.path('Path'),
    ...Field.tabs(
      Field.tab('Tab 1', {
        fields: {
          name: Field.path('Name'),
          entryLink: Field.link.multiple('Entry link'),
          list: Field.list('List field', {
            schema: {
              item: Config.type('Item', {
                fields: {
                  itemId: Field.text('Item id')
                }
              })
            }
          })
        }
      }),
      Field.tab('Tab 2', {
        fields: {
          name: Field.text('Name'),
          name2: Field.text('Name')
        }
      })
    )
  }
})

const Container = Config.type('TypeB', {
  contains: ['Page'],
  fields: {
    title: Field.text('Title'),
    path: Field.path('Path'),
    name: Field.text('name')
  }
})

const Fields = Config.document('Fields', {
  fields: {
    text: Field.text('Text field'),
    hello: Field.text('Validated text field', {
      help: 'This field only accepts "hello"',
      validate: value => {
        if (value !== 'hello') {
          return 'Only "hello" is allowed'
        }
      }
    }),
    richText: Field.richText('Rich text field'),
    select: Field.select('Select field', {
      options: {
        a: 'Option a',
        b: 'Option b'
      }
    }),
    number: Field.number('Number field', {
      minValue: 0,
      maxValue: 10
    }),
    check: Field.check('Check field', {description: 'Check me please'}),
    date: Field.date('Date field'),
    code: Field.code('Code field'),
    externalLink: Field.url('External link'),
    entry: Field.entry('Internal link'),
    entryWithCondition: Field.entry('With condition', {
      help: 'Show only entries of type Fields',
      condition: {_type: 'Fields'}
    }),
    linkMultiple: Field.link.multiple('Mixed links, multiple'),
    image: Field.image('Image link'),
    images: Field.image.multiple('Image link (multiple)'),
    file: Field.entry('File link'),
    withFields: Field.link('With extra fields', {
      fields: {
        fieldA: Field.text('Field A', {width: 0.5}),
        fieldB: Field.text('Field B', {width: 0.5})
      }
    }),
    multipleWithFields: Field.link.multiple('Multiple With extra fields', {
      fields: {
        fieldA: Field.text('Field A', {width: 0.5}),
        fieldB: Field.text('Field B', {width: 0.5, required: true})
      }
    }),
    list: Field.list('My list field', {
      schema: {
        Text: Config.type('Text', {
          fields: {
            title: Field.text('Item title'),
            text: Field.richText('Item body text')
          }
        }),
        Image: Config.type('Image', {
          fields: {
            image: Field.image('Image')
          }
        })
      }
    }),
    withInitial: Field.richText('With initial value', {
      required: true,
      initialValue: [
        {
          _type: 'paragraph',
          content: [
            {_type: 'text', text: 'This is a paragraph with initial value'}
          ]
        }
      ]
    }),
    nested: Field.richText('With nested blocks', {
      schema: {
        Inner: Config.type('Inner', {
          fields: {
            checkbox1: Field.check('Checkbox 1'),
            checkbox2: Field.check('Checkbox 2'),
            title: Field.text('Title'),
            content: Field.richText('Inner rich text')
          }
        }),

        NestLayout: Config.type('Nested layout fields', {
          fields: {
            object: Field.object('Object field', {
              fields: {
                fieldA: Field.text('Field A', {width: 0.5}),
                fieldB: Field.text('Field B', {width: 0.5})
              }
            }),
            ...Field.tabs(
              Field.tab('Tab A', {
                fields: {
                  tabA: Field.text('Tab A')
                }
              }),
              Field.tab('Tab B', {
                fields: {
                  tabB: Field.text('Tab B')
                }
              })
            )
          }
        })
      }
    })
  }
})

const main = Config.workspace('Main', {
  source: '.',
  roots: {
    pages: Config.root('Pages', {
      contains: ['Page', 'Container'],
      children: {
        entry1: Config.page({type: Page, fields: {title: 'Test title'}}),
        entry2: Config.page({
          type: Container,
          fields: {title: 'Entry 2'},
          children: {
            entry3: Config.page({type: Page, fields: {title: 'Entry 3'}})
          }
        }),
        container1: Config.page({
          type: Container,
          fields: {title: 'Container 1'}
        })
      }
    }),
    multiLanguage: Config.root('Multi language', {
      contains: ['Page', 'Container'],
      i18n: {
        locales: ['en', 'fr']
      },
      children: {
        localised1: Config.page({type: Page, fields: {title: 'Test title'}}),
        localised2: Config.page({
          type: Container,
          fields: {title: 'Entry 2'},
          children: {
            localised3: Config.page({type: Page, fields: {title: 'Entry 3'}})
          }
        })
      }
    }),
    media: createMediaRoot({
      dir: Config.page({
        type: MediaLibrary,
        fields: {title: 'Media folder'},
        children: {
          'file1.png': Config.page({
            type: MediaFile,
            fields: {
              title: 'File 1',
              path: 'file1.png',
              extension: '.png',
              size: 1000,
              width: 120,
              height: 120,
              hash: 'hash1',
              preview:
                '',
              averageColor: '#ffffff',
              focus: {x: 0.5, y: 0.5}
            }
          })
        }
      })
    })
  }
})

export const config = Config.create({
  schema: {Fields, Page, Container},
  workspaces: {main}
})

export async function createExample() {
  const db = new LocalDB(config)
  await db.sync()
  return db
}
